Diboson process split (ggZZ/qqZZ) and add missing Run 3 datasets - #121
Diboson process split (ggZZ/qqZZ) and add missing Run 3 datasets#121neeraj-1729 wants to merge 12 commits into
Conversation
- Restructure ZZ process hierarchy into ggZZ and qqZZ sub-processes - Update ZZ theory & per-decay-mode cross sections for 13 TeV and 13.6 TeV - Add process definitions for wg_lnug and wpwp_jj with XSDB cross sections - Add datasets for tttt, thq, thw, ttg (inclusive + pt-binned), wg_lnug, wpwp_jj in 2024 NanoAOD v15 campaign
ee29a3a to
2169f96
Compare
2169f96 to
63be119
Compare
- zz_qqbar: XSDB LO Pythia8 (12.14 pb) x k=1.51 = 18.3314 pb - zz_zqq_zll: GenXSecAnalyzer NLO (3.698 pb, mllmin4p0 sample) x k=1.15 = 4.253 pb - zz_zll_znunu: GenXSecAnalyzer NLO (0.9738 pb, UL mll>4 gridpack) x k=1.15 = 1.120 pb - zz_znunu_zqq: GenXSecAnalyzer NLO (4.487 pb) x k=1.15 = 5.160 pb - zz_zqq_zqq: XSDB madspin NLO (6.912 pb) x k=1.15 = 7.949 pb All NLO values confirmed via GenXSecAnalyzer on UL18 MiniAODv2 samples (CMSSW_15_0_9, 1M events each) or XSDB where generator setup is cleaner. XSDB 'LO' labels on amcatnloFXFX samples are misleading (Torben confirmed). k=1.15 applied uniformly (NLO->NNLO) consistent with 13.6 TeV treatment.
…x NLO EW) - wz_wlnu_zll (WZto3LNu): already updated in previous commit - wz_wqq_zll (WZto2L2Q): 7.568 x 1.08 = 8.17344 pb (verified CMS AN-2023/179) - wz_wlnu_zqq (WZtoLNu2Q): 15.87 x 1.08 = 17.1396 pb (GenXSecAnalyzer verified) - wz_wqq_zqq (WZto4Q): 24.97 x 1.08 = 26.9676 pb (GenXSecAnalyzer verified, NLO not LO) k-factor ~1.08 between NLO POWHEG and NNLO QCD x NLO EW (MATRIX): - MATRIX paper: https://arxiv.org/abs/1912.00068 - WZ Run3 paper: https://arxiv.org/pdf/2412.02477 13 TeV values still derived from inclusive wz via branching ratios.
- Split ww into ww_qqbar (id=8370) + ww_gg (id=8380), same pattern as ZZ - qqWW: XSDB Powheg NLO × k=1.14 (NLO→NNLO, arXiv:1605.02716) - ww_dl: 11.79 × 1.14 = 13.44 pb - ww_sl: 48.94 × 1.14 = 55.79 pb - ww_fh: 50.79 × 1.14 = 57.90 pb - ggWW: MCFM LO (fb, not pb) × k=1.41 (LO→NLO, arXiv:1511.08617) - Same-flavor (ee,μμ,ττ): 49.63 fb × 1.41 = 69.98 fb - Different-flavor (eμ,eτ,μτ): 2×49.63 fb × 1.41 = 139.96 fb - WW inclusive 13.6 TeV: LO Pythia 80.22 pb × k≈1.75 (LO→NNLO) - Reparent dilepton ggWW channels under ww_gg - Reparent qqWW decay modes under ww_qqbar - Updated campaign section headers
There was a problem hiding this comment.
Thanks for all the work!
I did a first pass and added some inline comments to dataset / process names to ensure consistency with current naming schemes throughout cmsdb.
I also browsed through the ewk process changes and before reviewing deeper, could you do the following?
In the comments for the tracking of cross section values, there are a lot of factors common to more than one cross section value (e.g. k-factors). Could you - at the right spots - assign these common values to variables together with comments detailing where the values come from? With that, it's totally ok use in-line computations instead of doing some multiplications manually and pasting the value.
You're actually doing this already in some spots, like
# XSDB NLO: 6.912 pb × k=1.15 = 7.9488 pb
13: Number(6.912) * 1.15,while in others, you write the computation in a comment like
# sum of ggZZ decay modes: 13 TeV: 3×2.703 + 3×5.423 = 24.378 fb
13: Number(24.378e-03),The latter can just become
# sum of ggZZ decay modes 3×2.703 + 3×5.423 = 24.378 fb
13: Number(2.703 + 5.423) * const.n_leps * 0.001,Process definitions (processes/ewk.py): - Add DYG (Zγ) process family: 14 processes (IDs 9700-9723) with NLO/LO cross sections from XSDB for inclusive and PTG-binned samples - Rename wg_lnug → wg_wlnu for naming consistency - Refactor diboson cross sections to use named k-factor variables: * ZZ: zz_k_nlo_to_nnlo=1.15, zz_k_lo_to_nnlo=1.51, zz_gg_k_lo_to_nlo=1.7 * WZ: wz_k_run2=1.19, wz_k_run3=1.08 * WW: ww_k_lo_to_nnlo=1.75, ww_k_nlo_to_nnlo=1.14, ww_gg_k_lo_to_nlo=1.41 - Use inline computations (XSDB × k) instead of hardcoded pre-multiplied values - Extract ggZZ/ggWW per-mode XSDB values as shared variables - Express ggZZ/ggWW/qqWW inclusive XS as computed sums using const.n_leps Campaign datasets: - Add 47 DYG datasets across 5 Run 3 campaigns (2022 preEE/postEE, 2023 preBPix/postBPix, 2024) - Add Wγ (wg_wlnu) dataset for 2024 campaign - Add same-sign WW (wpwp_jj) dataset for 2024 campaign - Add tH (thq, thw) datasets for 2024 campaign Dataset naming fixes (per review): - wpwp_jj_ewkqcd_madgraph → wpwp_jj_madgraph - wg_lnug_amcatnlo → wg_wlnu_amcatnlo - thq_ctcvcp_madgraph → thq_4f_madgraph - thw_ctcvcp_madgraph → thw_madgraph
|
Thanks for the detailed review, @riga. I've addressed all the feedback in the latest push. |
riga
left a comment
There was a problem hiding this comment.
Please find more inline suggestions below.
Before continuing, we'd have one comment / question on the new subprocess layer in both the ZZ and WW processes. You added the division into qq and gg-induced production and then re-attached existing processes to this new layer.
Let's use the following example to start the discussion:
zz_zee_zee = zz_gg.add_process((note that there are inline comments suggesting to change zz_gg → ggzz)
The fact that zz_zee_zee would now be g-induced only is rather implicit, and is purely driven by the existence of datasets in specific campaigns. The idea of processes behind was always for them to exist without strong ties to datasets or generator aspects .
Do you see any reason by existing subprocesses need to be re-attached to the ones you introduced?
| ) | ||
|
|
||
| # further ww decay modes | ||
| # qqWW decay modes (Powheg NLO) |
There was a problem hiding this comment.
Do you have a reference (mcm/fragment link) stating that this sample is indeed only qq-induced?
There was a problem hiding this comment.
I checked for ww_dl_powheg: https://cms-pdmv-prod.web.cern.ch/mcm/public/restapi/requests/get_setup/GEN-RunIII2024Summer24wmLHEGS-00309
the gridpack's flavor list directly, and only quark-antiquark initial states show up at Born level. No gluon-gluon entries anywhere, so this sample is indeed qq-induced only.
| ) | ||
|
|
||
| # further ww decay modes with specific leptons | ||
| # ggWW dilepton decay modes (MCFM LO) |
There was a problem hiding this comment.
Do you have a reference (mcm/fragment link) stating that this sample is indeed only gg-induced?
There was a problem hiding this comment.
For ww_wenu_wenu_pythia : https://cms-pdmv-prod.web.cern.ch/mcm/public/restapi/requests/get_setup/HIG-RunIII2024Summer24wmLHEGS-00775
Checked the gridpack's input card directly. It's running MCFM process 127, which is specifically the gluon-loop-induced WW process (no quark-initiated diagrams in it). So yes, this sample is gg-induced only.
| name="wpwp_jj_madgraph", | ||
| id=15515111, | ||
| processes=[procs.wpwp_jj], |
There was a problem hiding this comment.
| name="wpwp_jj_madgraph", | |
| id=15515111, | |
| processes=[procs.wpwp_jj], | |
| name="ww_ss_2j_madgraph", | |
| id=15515111, | |
| processes=[procs.ww_ss_2j], |
| "ww", "ww_qqbar", "ww_gg", | ||
| "ww_dl", "ww_sl", "ww_fh", | ||
| "ww_wenu_wenu", "ww_wenu_wmnu", "ww_wenu_wtnu", "ww_wmnu_wmnu", "ww_wmnu_wtnu", "ww_wtnu_wtnu", | ||
| "wpwp_jj", |
There was a problem hiding this comment.
| "wpwp_jj", | |
| "ww_ss_2j", |
| id=8220, | ||
| xsecs=multiply_xsecs(wz, const.br_w.had * const.br_z.clep), | ||
| xsecs={ | ||
| 13: multiply_xsecs(wz, const.br_w.had * const.br_z.clep)[13], |
There was a problem hiding this comment.
If you are just extracting a cross section at a single value, please use the verbose form
| 13: multiply_xsecs(wz, const.br_w.had * const.br_z.clep)[13], | |
| 13: wz.get_xsec(13) * const.br_w.had * const.br_z.clep, |
| ww_qqbar = ww.add_process( | ||
| name="ww_qqbar", |
There was a problem hiding this comment.
In this case, writing "qqbar" behind "ww" is misleading as it can be confused with decay products rather than the production mode.
| ww_qqbar = ww.add_process( | |
| name="ww_qqbar", | |
| qqww = ww.add_process( | |
| name="qqww", |
Please also change in all instances below as well as in __all__.
| ww_gg = ww.add_process( | ||
| name="ww_gg", |
There was a problem hiding this comment.
Same as above.
| ww_gg = ww.add_process( | |
| name="ww_gg", | |
| ggww = ww.add_process( | |
| name="ggww", |
Please also change in all instances below as well as in __all__.
| wpwp_jj = Process( | ||
| name="wpwp_jj", |
There was a problem hiding this comment.
| wpwp_jj = Process( | |
| name="wpwp_jj", | |
| ww_ss_2j = Process( | |
| name="ww_ss_2j", |
| zz_qqbar = zz.add_process( | ||
| name="zz_qqbar", |
There was a problem hiding this comment.
In this case, writing "qqbar" behind "zz" is misleading as it can be confused with decay products rather than the production mode.
| zz_qqbar = zz.add_process( | |
| name="zz_qqbar", | |
| qqzz = zz.add_process( | |
| name="qqzz", |
Please also change in all instances below as well as in __all__.
| zz_gg = zz.add_process( | ||
| name="zz_gg", |
There was a problem hiding this comment.
Same as above.
| zz_gg = zz.add_process( | |
| name="zz_gg", | |
| ggzz = zz.add_process( | |
| name="ggzz", |
Please also change in all instances below as well as in __all__.
Per Marcel's review suggestions: Process renames (prefix style for production modes): - zz_qqbar → qqzz - zz_gg → ggzz - ww_qqbar → qqww - ww_gg → ggww - wpwp_jj → ww_ss_2j (dataset: ww_ss_2j_madgraph) Reparent decay-mode subprocesses: - ZZ decay modes (zz_zll_zll, zz_zqq_zll, etc.) are now direct children of zz, not qqzz — processes should not be tied to production mechanism - WW decay modes (ww_dl, ww_sl, ww_fh, ww_wenu_*, etc.) are now direct children of ww, not qqww/ggww Replace multiply_xsecs with verbose form: - multiply_xsecs(wz, br)[13] → wz.get_xsec(13) * br - Remove unused multiply_xsecs import
|
Thanks for the feedback, @riga . You're right, there's no strong reason for the existing decay-mode subprocesses to be re-attached under the gg/qq production-mode layer. The production mechanism is a generator-level distinction and shouldn't dictate the process hierarchy. I've moved all decay-mode subprocesses (zz_zll_zll, zz_zee_zee, ww_dl, ww_wenu_wenu, etc.) back to being direct children of zz/ww. I've also applied all the other suggestions in this round: Renamed zz_qqbar → qqzz, zz_gg → ggzz, ww_qqbar → qqww, ww_gg → ggww, wpwp_jj → ww_ss_2j |
PR Description: Diboson Process Split + Missing Samples
Summary of Changes
ZZ Diboson Process Split (
processes/ewk.py):zzprocess tree into explicitzz_qqbar(zz_gg(zz_zll_zll,zz_zee_zee, etc.) are preserved for backwards compatibility.zz_qqbar: NLOzz_gg: LOzz_qqbar13 TeV inclusive: XSDB LOWW Diboson Process Split (
processes/ewk.py):wwprocess tree into explicitww_qqbar(ww_gg(ww_qqbardecay modes with explicit 13.6 TeV cross sections using XSDB Powheg NLOww_dl(WWto2L2Nu):ww_sl(WWtoLNu2Q):ww_fh(WWto4Q):ww_ggdilepton decay modes with explicit 13.6 TeV cross sections using MCFM LO (in fb, not pb)WZ Decay-Mode Cross Sections (
processes/ewk.py):wz_wlnu_zll(WZto3LNu):wz_wqq_zll(WZto2L2Q):wz_wlnu_zqq(WZtoLNu2Q):wz_wqq_zqq(WZto4Q):amcatnloFXFXis NLO — confirmed by 21% negative weight fraction)wz_wlnu_zll:New Process Definitions (
processes/ewk.py):wg_lnug:wpwp_jj:New Dataset Entries (Run 3 2024 Summer24 NanoAOD v15):
top.py:tttt_amcatnlo,ttg_amcatnlo,ttg_pt100to200_amcatnlo,ttg_pt200toinf_amcatnlohiggs.py:thq_ctcvcp_madgraph,thw_ctcvcp_madgraphewk.py:wpwp_jj_ewkqcd_madgraph,wg_lnug_amcatnloCross-Section References